﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Milkify.Interfaces;
using System.Reflection;

namespace Milkify
{
    public class MilkifyViewFactory : IViewFactory
    {
        public const string ViewTypeSuffix = "Control";

        private object mViewTypesLock = new object();
        private Dictionary<string, Type> mViewTypes;


        #region IViewFactory Members

        public IView Create(string viewName)
        {
            Type viewType = GetViewType(viewName);
            IView view = (IView)KernelContainer.Kernel.Get(viewType);
            return view;
        }

        public string GetViewName(IView view)
        {
            if (view == null)
                return null;
            string typeName = view.GetType().Name;
            return typeName.Substring(0, typeName.Length - ViewTypeSuffix.Length);
        }

        #endregion

        private Type GetViewType(string controllerName)
        {
            if (mViewTypes == null)
            {
                lock (mViewTypesLock)
                {
                    if (mViewTypes == null)
                    {
                        Dictionary<string, Type> viewTypes = new Dictionary<string, Type>();
                        foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
                        {
                            foreach (Type type in assembly.GetTypes())
                            {
                                if (IsView(type))
                                {
                                    string name = GetViewName(type);
                                    viewTypes.Add(name, type);
                                }
                            }
                        }

                        mViewTypes = viewTypes;
                    }
                }
            }

            return mViewTypes[controllerName];
        }

        private string GetViewName(Type type)
        {
            return type.Name.Substring(0, type.Name.Length - ViewTypeSuffix.Length);
        }

        internal static bool IsView(Type type)
        {
            if (type.IsInterface)
                return false;
            return type.Name.EndsWith(ViewTypeSuffix) && typeof(IView).IsAssignableFrom(type);
        }
    }
}
